package game;

import java.util.List;

public class TTTGameRules implements GameRules
{

	public TTTGameRules(Game game, Board board)
	{
		itsGame = game;
		itsBoard = board;
		currentPlayerPosition = 0;
	}
	
	/*
	 * operation isFinished()
	 * a game is finished if one of the following is true:
	 * 1. there is a winner
	 * 2. all 9 steps are done (the board is full)
	 * 3. maximum moves have been played
	 */
	@Override
	public boolean isFinished()
	{
		return (getWinner() != null) || (itsGame.getStep() == 9) || (itsGame.getStep() == itsGame.getNumMoves());
	}
	
	@Override
	public Player nextPlayer(List<Player> players)
	{
		if(currentPlayerPosition >= players.size())
		{
			return null;
		}
		else
		{
			Player player = players.get(currentPlayerPosition);
			currentPlayerPosition++;
			currentPlayerPosition %= 2;
			return player;
		}
	}
	
	@Override
	public int getCompletionStatus()
	{
		if(getWinner() != null)
		{
			// there is a winner
			return 1;
		}
		else if(itsGame.getStep() == 9)
		{
			// draw
			return 0;
		}
		else
		{
			// stopped
			return -1;
		}
	}

	@Override
	public Player getWinner()
	{
		String descriptor = getWinnerModelDescriptor();
		if(descriptor == null)
		{
			return null;
		}
		else
		{
			List<Player> playerList = itsGame.getItsPlayers();
			if(descriptor.equals("X"))
			{
				return playerList.get(0);
			}
			else
			{
				// descriptor is "O"
				return playerList.get(1);
			}
		}	
	}
	
	@Override
	public Player getWinning()
	{
		return null;
	}
	
	@Override
	public int getMaximumPossibleMoves()
	{
		return 9;
	}
	
	private String getWinnerModelDescriptor()
	{
		String descriptor = null;
		
		for(int i = 0; i < 3; ++i)
		{
			descriptor = checkRow(i);
			if(descriptor != null)
			{
				return descriptor;
			}
		}
		
		for(int j = 0; j < 3; ++j)
		{
			descriptor = checkColumn(j);
			if(descriptor != null)
			{
				return descriptor;
			}
		}
		
		descriptor = checkDiagonal1();
		if(descriptor != null)
		{
			return descriptor;
		}
		
		descriptor = checkDiagonal2();
		if(descriptor != null)
		{
			return descriptor;
		}
		
		return descriptor;
	}
	
	private String checkRow(int row)
	{
		if(itsBoard.getGameModel(new GridPosition(row, 0)) == null ||
		   itsBoard.getGameModel(new GridPosition(row, 1)) == null ||
		   itsBoard.getGameModel(new GridPosition(row, 2)) == null)
		{
			return null;
		}
		
		String r0 = itsBoard.getGameModel(new GridPosition(row, 0)).getDescriptor();
		String r1 = itsBoard.getGameModel(new GridPosition(row, 1)).getDescriptor();
		String r2 = itsBoard.getGameModel(new GridPosition(row, 2)).getDescriptor();

		if(r0.equals(r1) && r1.equals(r2))
		{
			return new String(r0);
		}
		else
		{
			return null;
		}
	}
	
	private String checkColumn(int column)
	{
		if(itsBoard.getGameModel(new GridPosition(0, column)) == null ||
		   itsBoard.getGameModel(new GridPosition(1, column)) == null ||
		   itsBoard.getGameModel(new GridPosition(2, column)) == null)
		{
			return null;
		}
		
		String c0 = itsBoard.getGameModel(new GridPosition(0, column)).getDescriptor();
		String c1 = itsBoard.getGameModel(new GridPosition(1, column)).getDescriptor();
		String c2 = itsBoard.getGameModel(new GridPosition(2, column)).getDescriptor();

		if(c0.equals(c1) && c1.equals(c2))
		{
			return new String(c0);
		}
		else
		{
			return null;
		}
	}

	private String checkDiagonal1()
	{
		if(itsBoard.getGameModel(new GridPosition(0, 0)) == null ||
		   itsBoard.getGameModel(new GridPosition(1, 1)) == null ||
		   itsBoard.getGameModel(new GridPosition(2, 2)) == null)
		{
			return null;
		}
		
		String d0 = itsBoard.getGameModel(new GridPosition(0, 0)).getDescriptor();
		String d1 = itsBoard.getGameModel(new GridPosition(1, 1)).getDescriptor();
		String d2 = itsBoard.getGameModel(new GridPosition(2, 2)).getDescriptor();
		if(d0.equals(d1) && d1.equals(d2))
		{
			return new String(d0);
		}
		else
		{
			return null;
		}
	}
	
	private String checkDiagonal2()
	{
		if(itsBoard.getGameModel(new GridPosition(0, 2)) == null ||
		   itsBoard.getGameModel(new GridPosition(1, 1)) == null ||
		   itsBoard.getGameModel(new GridPosition(2, 0)) == null)
		{
			return null;
		}
		
		String d0 = itsBoard.getGameModel(new GridPosition(0, 2)).getDescriptor();
		String d1 = itsBoard.getGameModel(new GridPosition(1, 1)).getDescriptor();
		String d2 = itsBoard.getGameModel(new GridPosition(2, 0)).getDescriptor();
		if(d0.equals(d1) && d1.equals(d2))
		{
			return new String(d0);
		}
		else
		{
			return null;
		}
	}
	
	
	private Board itsBoard;
	private Game itsGame;
	private int currentPlayerPosition;
}
